import 'package:flame/collisions.dart';
import 'package:flame/components.dart';
import 'package:flame/events.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
import 'package:flame/palette.dart';
import 'package:flame/sprite.dart';
import 'package:flame_spine/flame_spine.dart';
import 'package:flame_tiled/flame_tiled.dart';
import 'package:flutter/material.dart';
import 'package:flutterabc/EnemyComponent.dart';

import 'BulletComponent.dart';
import 'CollidableObject.dart';
import 'MapManager.dart';
import 'PlayerComponent.dart';
import 'PlayerComponent2.dart';
import 'astar_2d.dart';

void main() async{
  await initSpineFlutter();
  WidgetsFlutterBinding.ensureInitialized();
  runApp(
    GameWidget(
      game: MyGame(),
    ),
  );
}

/// This example simply adds a rotating white square on the screen.
/// If you press on a square, it will be removed.
/// If you press anywhere else, another square will be added.
class MyGame extends FlameGame
    with HasKeyboardHandlerComponents, HasCollisionDetection, PanDetector,TapDetector {

  late RectangleComponent tagEntity;
  late PlayerComponent2 player;
  late EnemyComponent enemy;

  PositionComponent? dragEntity;

  //PlayerStateComponent? state;

  late PathFinder2D pathFinder;

  Iterable<Vector2>? path;
  var mapManager = MapManager();

  @override
  Future<void> onLoad() async {
    tagEntity = RectangleComponent(
        position: Vector2(50.0, 50.0),
        size: Vector2.all(20.0),
        paint: BasicPalette.blue.paint());
    tagEntity.add(RectangleHitbox());
    player = PlayerComponent2(size / 2);
    enemy = EnemyComponent(
        position: Vector2(90.0, 50.0),
        size: Vector2.all(20.0),
        paint: BasicPalette.darkPink.paint());
    add(player);
    add(tagEntity);
    add(enemy);
    //enemy.moveTo(player);
    camera.follow(player);
    //var state = PlayerStateComponent(size/2);
    //state.loadIdleState( 0.2);
    //add(state);

    mapManager.initMap(this);

    //path
    pathFinder = PathFinder2D(
        // 你的地图逻辑，返回 (x, y) 是否可以通过
        // isPassable: (x, y) {
        //   // 你的地图逻辑，返回 (x, y) 是否可以通过
        //   return true;
        // }
        isPassable: (x, y) => mapManager.isPassable(x, y));
    //end path
  }

  @override
  void onPanDown(DragDownInfo info) {
    if (tagEntity.containsPoint(info.eventPosition.global)) {
      dragEntity = tagEntity;
      print("抓取tagEntity=${dragEntity?.position}");
    }

    //点击回获取鼠标
    var clickPosition = info.eventPosition.global;
    var dir = (clickPosition - player.center).normalized();

    final childs = componentsAtPoint(info.eventPosition.global);
    final first = childs.firstWhere(
      (component) => component is RectangleComponent,
      orElse: () => Component(),
    );
    if (first is RectangleComponent) {
      print("点击到=${first}");
      BulletComponent(
              dir: dir, position: player.center + dir * player.width / 2)
          .addToParent(this);
    } else {
      //player.moveTo(gamePosition);
      var moveX = true;
      while (!mapManager.isPassable(clickPosition.x, clickPosition.y)) {
        if (moveX) {
          clickPosition = Vector2(clickPosition.x - 16, clickPosition.y);
        } else {
          clickPosition = Vector2(clickPosition.x, clickPosition.y - 16);
        }
        moveX = !moveX;
      }
      Vector2 start = Vector2(
          player.position.x.floorToDouble(), player.position.y.floorToDouble());
      Vector2 goal = Vector2(
          clickPosition.x.floorToDouble(), clickPosition.y.floorToDouble());
      print("path start...");
      path = pathFinder.findPath(start, goal);
      print("path end...");
      final iterator = path?.iterator;
      if (iterator != null) {
        while (iterator.moveNext()) {
          // 倒计时结束时输出
          //print('path = ${iterator.current}');
          var r = RectangleComponent(
              position: iterator.current,
              size: Vector2.all(2.0),
              paint: BasicPalette.blue.paint());
          add(r);
        }
      }

      print("start=$start goal=$goal path=$path");
      if (path != null) {
        var list = filteredPath(path!);
        //print("list=$list");
        player.moveToList(list);
        //LineRenderer(points: path!);
      } else {
        print("No path found");
      }
    }
    //print("d=${d} dir=$dir  sq=$sq");

    //print("onMouseMove.gamePosition=${gamePosition}");
    //player.moveTo(gamePosition);
  }

  Iterable<Vector2> filteredPath(Iterable<Vector2> path) {
    if (path.length <= 32) {
      return [path.first, path.last];
    } else {
      List<Vector2> list = [path.first];
      var forList = path.toList();
      for (int i = 0; i < path.length; i += 32) {
        list.add(forList[i]);
      }
      list.add(forList.last);
      return list;
    }
  }

  @override
  void onPanUpdate(DragUpdateInfo info) {
    dragEntity?.position = info.eventPosition.global - dragEntity!.size / 2;
  }

  @override
  void onPanEnd(DragEndInfo info) {
    //print("放开tagEntity=${dragEntity?.position}");
    dragEntity = null; //释放dragEntity
  }

  void loadMySprite() async {
    // 加载九宫格图片
    final image = await images.load('sword_2x.png');
    // 创建 SpriteSheet
    final spriteSheet = SpriteSheet.fromColumnsAndRows(
      image: image,
      columns: 6,
      rows: 10,
    );
    // 创建动画组件
    final animationComponent = SpriteAnimationComponent(
      animation: spriteSheet.createAnimation(
        row: 0,
        stepTime: 0.2,
        to: 6,
      ),
      position: size / 3,
    );
    animationComponent.debugMode = true;
    // 将动画组件添加到游戏中
    add(animationComponent);
  }
}
